package com.khadi.testcase.view.workflow;

import info.clearthought.layout.TableLayout;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.border.EtchedBorder;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import com.khadi.testcase.util.HtmlObjectFinder;
import com.khadi.testcase.util.SessionUtil;
import com.khadi.testcase.util.UIHelper;
import com.khadi.testcase.view.ITestObserver;
import com.khadi.testcase.view.IWindowContent;
import com.khadi.testcase.view.model.CustomComboModel;
import com.khadi.testcase.view.model.FieldTableModel;
import com.khadi.testcase.view.model.HtmlFieldModel;
import com.khadi.testcase.view.model.IdValueModel;

public class HtmlComponentTab implements IWindowContent, ActionListener {
	private FieldTableModel fieldTableModel;

	private JComboBox cbSearchBy;
	private JTextField tfSearchBy;
	private static final String SEARCH_BY_FIND = "SEARCH_BY_FIND";
	private static final String ACTION_FETCH = "ACTION_FETCH";
	private ITestObserver observer;
	private JTable tblFields;

	private HtmlObjectFinder htmlObjectFinder;

	public HtmlComponentTab(ITestObserver observer) {
		this.observer = observer;
	}

	@Override
	public List<HtmlFieldModel> getData() {
		List<HtmlFieldModel> list = new LinkedList<HtmlFieldModel>();
		int[] selectedRows = tblFields.getSelectedRows();

		for (int selectedIndex : selectedRows) {
			list.add(fieldTableModel.getData().get(selectedIndex));
		}
		return list;
	}

	@Override
	public Component getView() {
		double[] columns = new double[] { -2, -1, -2, -2 };
		double[] rows = new double[] { -2, -2, -1, -2 };
		TableLayout screenFetchLayout = new TableLayout(columns, rows);
		screenFetchLayout.setHGap(5);
		screenFetchLayout.setVGap(5);

		JPanel screenFetchPanel = new JPanel(screenFetchLayout);

		screenFetchPanel.setBorder(BorderFactory
				.createEtchedBorder(EtchedBorder.LOWERED));

		fetchScreenComponents(screenFetchPanel);
		return screenFetchPanel;
	}

	private void fetchScreenComponents(JPanel screenFetchPanel) {

		JButton btnFetch = new JButton("Find All");
		btnFetch.setActionCommand(ACTION_FETCH);
		btnFetch.addActionListener(this);
		screenFetchPanel.add(btnFetch, "0,0");

		JLabel lbSearchBY = new JLabel("Search By");
		tfSearchBy = new JTextField();

		CustomComboModel<IdValueModel<String, String>> searchByModel = new CustomComboModel<IdValueModel<String, String>>();
		searchByModel.setData(HtmlObjectFinder.getSearchByList());
		cbSearchBy = new JComboBox(searchByModel);
		// cbSearchBy.setRenderer(getSearchRenderer());

		JButton btnFind = new JButton("Find");
		btnFind.setActionCommand(SEARCH_BY_FIND);
		btnFind.addActionListener(this);

		screenFetchPanel.add(lbSearchBY, "0,1");
		screenFetchPanel.add(tfSearchBy, "1,1");
		screenFetchPanel.add(cbSearchBy, "2,1");
		screenFetchPanel.add(btnFind, "3,1");

		// Table
		fieldTableModel = new FieldTableModel(getColumnNames());

		tblFields = new JTable(fieldTableModel);

		tblFields.setRowHeight(20);

		tblFields.getSelectionModel().setSelectionMode(
				ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

		JScrollPane tblScrollPane = new JScrollPane(tblFields);
		screenFetchPanel.add(tblScrollPane, "0,2,3,2");

		JPanel nextPanel = new JPanel();
		nextPanel.setLayout(new BorderLayout(10, 10));
		JLabel lbNext = new JLabel(
				UIHelper.getImageIcon(UIHelper.IMG_RIGHT_ARROW_MARK));

		lbNext.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {

				observer.notify(HtmlComponentTab.this);
			}

		});

		nextPanel.add(lbNext, BorderLayout.EAST);
		screenFetchPanel.add(nextPanel, "3,3");
	}

	private ComboRenderer getSearchRenderer() {

		return new ComboRenderer();
	}

	private String[] getColumnNames() {

		return new String[] { "Id", "Name", "Type", "Value", "Class Name" };
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equals(ACTION_FETCH)) {
			doFetchScreenFields();
		} else if (e.getActionCommand().equals(SEARCH_BY_FIND)) {
			doFetchBasedOnSearchBy();
		}
	}

	private void doFetchBasedOnSearchBy() {
		String searchByText = tfSearchBy.getText();
		List<HtmlFieldModel> previousList = fieldTableModel.getData();
		if (searchByText != null) {
			IdValueModel<String, String> searchBy = (IdValueModel<String, String>) cbSearchBy
					.getSelectedItem();
			previousList.addAll(getHtmlObjectFinder().getHtmlFieldModelList(
					searchByText, searchBy));
		}

		fieldTableModel.fireTableDataChanged();
	}

	private void doFetchScreenFields() {
		List<WebElement> findElements = getFindAllWebElements();

		List<HtmlFieldModel> guiFieldList = new ArrayList<HtmlFieldModel>();

		for (WebElement webElement : findElements) {

			String elementName = webElement.getAttribute("name");

			String elementType = webElement.getAttribute("type");

			String elementId = webElement.getAttribute("id");
			String className = webElement.getAttribute("className");

			String value = webElement.getText();

			guiFieldList.add(new HtmlFieldModel(elementName, elementType,
					elementId, value, className));

		}

		fieldTableModel.setData(guiFieldList);

	}

	private List<WebElement> getFindAllWebElements() {
		WebDriver driver = getWebDriver();
		List<WebElement> findElements = driver
				.findElements(By.tagName("input"));

		findElements.addAll(driver.findElements(By.tagName("button")));

		findElements.addAll(driver.findElements(By
				.className("z-toolbarbutton-cnt")));
		return findElements;
	}

	private WebDriver getWebDriver() {
		return (WebDriver) SessionUtil.getInstance().getSessionMap()
				.get(SessionUtil.WEB_DRIVER);
	}

	@Override
	public void postData(Object object) {
		// TODO Auto-generated method stub

	}

	@Override
	public void preData(Object object) {
		// TODO Auto-generated method stub

	}

	public HtmlObjectFinder getHtmlObjectFinder() {
		if (htmlObjectFinder == null) {
			htmlObjectFinder = new HtmlObjectFinder(getWebDriver());
		}
		return htmlObjectFinder;
	}

	private class ComboRenderer extends JLabel implements ListCellRenderer {

		public ComboRenderer() {
		}

		/**
		 * 
		 */
		private static final long serialVersionUID = 6692968410426397547L;

		@Override
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			if (isSelected) {
				setBackground(list.getSelectionBackground());
				setForeground(list.getSelectionForeground());
			} else {
				setBackground(list.getBackground());
				setForeground(list.getForeground());
			}

			setFont(list.getFont());
			if (value instanceof IdValueModel) {
				IdValueModel<String, String> idValue = (IdValueModel<String, String>) value;
				this.setText(idValue.getE());
			}
			return this;
		}

	}
}
